SDKDemoCtl.cpp


// SDKDemoCtl.cpp : Implementation of the CSDKDemoCtrl OLE control class.

#include "stdafx.h"
#include "SDKDemo.h"
#include "SDKDemoCtl.h"
#include "SDKDemoPpg.h"


#ifdef _DEBUG
#define new DEBUG_NEW
#undef THIS_FILE
static char THIS_FILE[] = __FILE__;
#endif

// Make a "missing" optional parameter
COleVariant varMissing((long)DISP_E_PARAMNOTFOUND, VT_ERROR);

IMPLEMENT_DYNCREATE(CSDKDemoCtrl, COleControl)


/////////////////////////////////////////////////////////////////////////////
// Message map

BEGIN_MESSAGE_MAP(CSDKDemoCtrl, COleControl)
	//{{AFX_MSG_MAP(CSDKDemoCtrl)
	ON_WM_CREATE()
	ON_WM_LBUTTONDOWN()
	ON_WM_LBUTTONUP()
	ON_WM_MOUSEMOVE()
	//}}AFX_MSG_MAP
	ON_OLEVERB(AFX_IDS_VERB_EDIT, OnEdit)
	ON_OLEVERB(AFX_IDS_VERB_PROPERTIES, OnProperties)
END_MESSAGE_MAP()


/////////////////////////////////////////////////////////////////////////////
// Dispatch map

BEGIN_DISPATCH_MAP(CSDKDemoCtrl, COleControl)
	//{{AFX_DISPATCH_MAP(CSDKDemoCtrl)
	DISP_PROPERTY_NOTIFY(CSDKDemoCtrl, "FileName", m_strFileName, OnFileNameChanged, VT_BSTR)
	DISP_PROPERTY_NOTIFY(CSDKDemoCtrl, "HideLayers", m_strHideLayers, OnHideLayersChanged, VT_BSTR)
	DISP_PROPERTY_EX(CSDKDemoCtrl, "AllLayers", GetAllLayers, SetNotSupported, VT_BSTR)
	DISP_STOCKPROP_BACKCOLOR()
	//}}AFX_DISPATCH_MAP
	//}}AFX_DISPATCH_MAP
	DISP_FUNCTION_ID(CSDKDemoCtrl, "AboutBox", DISPID_ABOUTBOX, AboutBox, VT_EMPTY, VTS_NONE)
END_DISPATCH_MAP()


/////////////////////////////////////////////////////////////////////////////
// Event map

BEGIN_EVENT_MAP(CSDKDemoCtrl, COleControl)
	//{{AFX_EVENT_MAP(CSDKDemoCtrl)
	// NOTE - ClassWizard will add and remove event map entries
	//    DO NOT EDIT what you see in these blocks of generated code !
	//}}AFX_EVENT_MAP
END_EVENT_MAP()


/////////////////////////////////////////////////////////////////////////////
// Property pages

// TODO: Add more property pages as needed.  Remember to increase the count!
BEGIN_PROPPAGEIDS(CSDKDemoCtrl, 1)
	PROPPAGEID(CSDKDemoPropPage::guid)
END_PROPPAGEIDS(CSDKDemoCtrl)


/////////////////////////////////////////////////////////////////////////////
// Initialize class factory and guid

IMPLEMENT_OLECREATE_EX(CSDKDemoCtrl, "SDKDEMO.SDKDemoCtrl.1",
	0xa63e6664, 0xc85f, 0x11d0, 0x9b, 0x3b, 0x44, 0x45, 0x53, 0x54, 0, 0)


/////////////////////////////////////////////////////////////////////////////
// Type library ID and version

IMPLEMENT_OLETYPELIB(CSDKDemoCtrl, _tlid, _wVerMajor, _wVerMinor)


/////////////////////////////////////////////////////////////////////////////
// Interface IDs

const IID BASED_CODE IID_DSDKDemo =
		{ 0xa63e6662, 0xc85f, 0x11d0, { 0x9b, 0x3b, 0x44, 0x45, 0x53, 0x54, 0, 0 } };
const IID BASED_CODE IID_DSDKDemoEvents =
		{ 0xa63e6663, 0xc85f, 0x11d0, { 0x9b, 0x3b, 0x44, 0x45, 0x53, 0x54, 0, 0 } };


/////////////////////////////////////////////////////////////////////////////
// Control type information

static const DWORD BASED_CODE _dwSDKDemoOleMisc =
	OLEMISC_ACTIVATEWHENVISIBLE |
	OLEMISC_SETCLIENTSITEFIRST |
	OLEMISC_INSIDEOUT |
	OLEMISC_CANTLINKINSIDE |
	OLEMISC_RECOMPOSEONRESIZE;

IMPLEMENT_OLECTLTYPE(CSDKDemoCtrl, IDS_SDKDEMO, _dwSDKDemoOleMisc)


/////////////////////////////////////////////////////////////////////////////
// CSDKDemoCtrl::CSDKDemoCtrlFactory::UpdateRegistry -
// Adds or removes system registry entries for CSDKDemoCtrl

BOOL CSDKDemoCtrl::CSDKDemoCtrlFactory::UpdateRegistry(BOOL bRegister)
{
	// TODO: Verify that your control follows apartment-model threading rules.
	// Refer to MFC TechNote 64 for more information.
	// If your control does not conform to the apartment-model rules, then
	// you must modify the code below, changing the 6th parameter from
	// afxRegInsertable | afxRegApartmentThreading to afxRegInsertable.

	if (bRegister)
		return AfxOleRegisterControlClass(
			AfxGetInstanceHandle(),
			m_clsid,
			m_lpszProgID,
			IDS_SDKDEMO,
			IDB_SDKDEMO,
			afxRegInsertable | afxRegApartmentThreading,
			_dwSDKDemoOleMisc,
			_tlid,
			_wVerMajor,
			_wVerMinor);
	else
		return AfxOleUnregisterClass(m_clsid, m_lpszProgID);
}


/////////////////////////////////////////////////////////////////////////////
// CSDKDemoCtrl::CSDKDemoCtrl - Constructor

CSDKDemoCtrl::CSDKDemoCtrl() :
	m_bFirstDraw(TRUE),
	m_pIApp(NULL),
	m_pIDrawing(NULL),
	m_pView(NULL),
	m_ptMouseDown(CPoint(0, 0)),
	m_dragX(0),
	m_dragY(0),
	m_bDragging(FALSE),
	m_pDragGraphic(NULL)
{
	InitializeIIDs(&IID_DSDKDemo, &IID_DSDKDemoEvents);
	VariantInit(&m_dragOutline);
}


/////////////////////////////////////////////////////////////////////////////
// CSDKDemoCtrl::~CSDKDemoCtrl - Destructor

CSDKDemoCtrl::~CSDKDemoCtrl()
{
	VariantClear(&m_dragOutline);
	CloseDrawing();
	if (m_pIApp != NULL)
		m_pIApp->Release();
}

BOOL CSDKDemoCtrl::OpenDrawing(const CString& strFileName)
{
	if (m_pIApp == NULL)
		return FALSE;
	
	Drawings* pDrawings;
	HRESULT hRes = m_pIApp->get_Drawings(&pDrawings);
	if (FAILED(hRes))
		return FALSE;

	// Get the file name into a BSTR
	BSTR bstrPath = strFileName.AllocSysString();

	// Add the drawing to the drawings collection
	IDrawing* pIDrawing;
	hRes = pDrawings->Open(bstrPath, &varMissing, &varMissing, &pIDrawing);

	// Free the system memory for the BSTR
	::SysFreeString(bstrPath);

	if (SUCCEEDED(hRes))
	{
		Views* pViews;
		hRes = pIDrawing->get_Views(&pViews);
		if (SUCCEEDED(hRes))
		{
			View* pView;
			hRes = pViews->Add(&varMissing, &varMissing, &pView);
			if (SUCCEEDED(hRes))
			{
				CloseDrawing();

				m_pIDrawing = pIDrawing;
				m_pView = pView;
				Layers* pLayers;
				if (SUCCEEDED(m_pIDrawing->get_Layers(&pLayers)))
				{
					COleVariant varIndex(0L);
					for ( ; ; varIndex.lVal++)
					{
						Layer* pLayer;
						if (FAILED(pLayers->get_Item(&varIndex, &pLayer)))
							break;
						BSTR bstrName = NULL;
						if (SUCCEEDED(pLayer->get_Name(&bstrName)))
						{
							CString str(bstrName);
							if (!m_strAllLayers.IsEmpty())
								m_strAllLayers += "\n";
							m_strAllLayers += str;
							::SysFreeString(bstrName);
						}
					}
				}
				InvalidateControl();
			}
			pViews->Release();
		}
		if (FAILED(hRes))
		{
			pIDrawing->Close(&varMissing, &varMissing, &varMissing);
			pIDrawing->Release();
		}
	}
	pDrawings->Release();
	return SUCCEEDED(hRes);
}

void CSDKDemoCtrl::CloseDrawing()
{
	if (m_pDragGraphic != NULL)
	{
		m_pDragGraphic->Release();
		m_pDragGraphic = NULL;
	}
	m_bDragging = FALSE;

	m_strAllLayers.Empty();
	m_strHideLayers.Empty();
	if (m_pView != NULL)
	{
		m_pView->Release();
		m_pView = NULL;
	}
	if (m_pIDrawing != NULL)
	{
		m_pIDrawing->Close(&varMissing, &varMissing, &varMissing);
		m_pIDrawing->Release();
		m_pIDrawing = NULL;
	}
	m_bFirstDraw = TRUE;
}


/////////////////////////////////////////////////////////////////////////////
// CSDKDemoCtrl::OnDraw - Drawing function

void CSDKDemoCtrl::OnDraw(
			CDC* pdc, const CRect& rcBounds, const CRect& rcInvalid)
{
	{
		CBrush colorBrush;
		CBrush* backBrush;
		if (m_pView == NULL)
			backBrush = CBrush::FromHandle((HBRUSH)GetStockObject(LTGRAY_BRUSH));
		else
		{
			colorBrush.CreateSolidBrush(GetBackColor());
			backBrush = &colorBrush;
		}
		pdc->FillRect(rcBounds, backBrush);
	}
	if (m_pView == NULL)
		return;

	HDC hDC = pdc->m_hDC;
	m_pView->put_Update(FALSE);
	m_pView->put_DC((long)hDC);
	m_pView->put_MappingMode(MM_TEXT);
	m_pView->put_Margins(FALSE);
	m_pView->put_FixedAspectRatio(TRUE);
	m_pView->put_ScreenLeft(rcBounds.left);
	m_pView->put_ScreenTop(rcBounds.top);
	m_pView->put_ScreenWidth(rcBounds.Width());
	m_pView->put_ScreenHeight(rcBounds.Height());
	if (m_bFirstDraw)
	{
		m_bFirstDraw = FALSE;
		m_pView->ZoomToExtents();
	}
	m_pView->Refresh();
}


/////////////////////////////////////////////////////////////////////////////
// CSDKDemoCtrl::DoPropExchange - Persistence support

void CSDKDemoCtrl::DoPropExchange(CPropExchange* pPX)
{
	ExchangeVersion(pPX, MAKELONG(_wVerMinor, _wVerMajor));
	COleControl::DoPropExchange(pPX);

	PX_String(pPX, _T("FileName"), m_strFileName);
	PX_String(pPX, _T("HideLayers"), m_strHideLayers);
}


/////////////////////////////////////////////////////////////////////////////
// CSDKDemoCtrl::OnResetState - Reset control to default state

void CSDKDemoCtrl::OnResetState()
{
	COleControl::OnResetState();  // Resets defaults found in DoPropExchange

	// TODO: Reset any other control state here.
}


/////////////////////////////////////////////////////////////////////////////
// CSDKDemoCtrl::AboutBox - Display an "About" box to the user

void CSDKDemoCtrl::AboutBox()
{
	CDialog dlgAbout(IDD_ABOUTBOX_SDKDEMO);
	dlgAbout.DoModal();
}


/////////////////////////////////////////////////////////////////////////////
// CSDKDemoCtrl message handlers

void CSDKDemoCtrl::OnFileNameChanged() 
{
	OpenDrawing(m_strFileName);
	SetModifiedFlag();
}

UINT CountStrings(const char* lpsz)
{
	if (lpsz == NULL)
		return 0;
	UINT n = 0;
	const char* p = lpsz;
	while (*p)
	{
		++n;
		p = strchr(p, '\n');
		if (p == NULL)
			break;
		++p;
	}
	return n;
}


BOOL CSDKDemoCtrl::PreCreateWindow(CREATESTRUCT& cs) 
{
	// Connect to the server
	static const CLSID CLSID_XApplication = {0x6A481801,0xE531,0x11CF,{0xA1,0x15,0x00,0xA0,0x24,0x15,0x8D,0xAF}};
	static const IID IID_IApplication = {0x6A481101,0xE531,0x11CF,{0xA1,0x15,0x00,0xA0,0x24,0x15,0x8D,0xAF}};

	HRESULT hRes = CoCreateInstance(
		CLSID_XApplication,	//Class identifier (CLSID) of the object
		NULL,	//Object is or isn't part of an aggregate
		CLSCTX_INPROC_SERVER,	//Context for running executable code
		IID_IApplication,	//Interface identifier
		(void**)&m_pIApp	//Points to requested interface pointer
	);

	if (FAILED(hRes))
	{
		AfxMessageBox("Couldn't create application object (in-process server)!");
		return FALSE;
	}
	
	return COleControl::PreCreateWindow(cs);
}

int CSDKDemoCtrl::OnCreate(LPCREATESTRUCT lpCreateStruct) 
{
	if (COleControl::OnCreate(lpCreateStruct) == -1)
		return -1;
	
	// If we are started from a property set with a FileName
	// tTry to open the drawing now
	if (!m_strFileName.IsEmpty())
		OpenDrawing(m_strFileName);
	
	return 0;
}

void CSDKDemoCtrl::OnHideLayersChanged() 
{
	if (m_pIDrawing != NULL)
	{
		Layers* pLayers;
		if (SUCCEEDED(m_pIDrawing->get_Layers(&pLayers)))
		{
			COleVariant varIndex(0L);
			for ( ; ; varIndex.lVal++)
			{
				Layer* pLayer;
				if (FAILED(pLayers->get_Item(&varIndex, &pLayer)))
					break;
				pLayer->put_Visible(TRUE);
				pLayer->Release();
			}
			for (int i = 0; ; i++)
			{
				CString str;
				if (!AfxExtractSubString(str, m_strHideLayers, i, '\n'))
					break;
				if (!str.IsEmpty())
				{
					Layer* pLayer;
					COleVariant varName(str);
					if (SUCCEEDED(pLayers->get_Item(&varName, &pLayer)))
					{
						pLayer->put_Visible(FALSE);
						pLayer->Release();
					}
				}
			}
		}
	}
		
	SetModifiedFlag();
}

BSTR CSDKDemoCtrl::GetAllLayers() 
{
	return m_strAllLayers.AllocSysString();
}

BOOL CSDKDemoCtrl::BeginDrag(const CPoint& point)
{
	VariantClear(&m_dragOutline);
	SAFEARRAYBOUND bound;
	bound.cElements = 0;
	bound.lLbound = 0;
	m_dragOutline.vt = VT_ARRAY|VT_R8;
	m_dragOutline.parray = ::SafeArrayCreate(VT_R8, 1, &bound);
	HRESULT hRes = m_pDragGraphic->CreateDragOutline(&m_dragOutline);
	if (FAILED(hRes))
		return FALSE;

	m_bDragging = TRUE;
	m_pDragGraphic->put_Visible(FALSE);
	InvalidateControl();
	UpdateWindow();

	SetCapture();
	CDC* pDC = GetDC();
	m_pView->put_DC((long)pDC->m_hDC);
	VARIANT varState;
	varState.vt = VT_I4;
	varState.lVal = imsiDragBegin;
	hRes = m_pView->DragOutline(&m_dragOutline, m_ptMouseDown.x, m_ptMouseDown.y, &varState);
	varState.lVal = imsiDragContinue;
	hRes = m_pView->DragOutline(&m_dragOutline, point.x, point.y, &varState);
	ReleaseDC(pDC);
	return TRUE;
}

void CSDKDemoCtrl::Drag(const CPoint& point)
{
	if (m_pView == NULL)
		return;

	CDC* pDC = GetDC();
	m_pView->put_DC((long)pDC->m_hDC);
	VARIANT varState;
	varState.vt = VT_I4;
	varState.lVal = imsiDragContinue;
	HRESULT hRes = m_pView->DragOutline(&m_dragOutline, point.x, point.y, &varState);
	ReleaseDC(pDC);
}

void CSDKDemoCtrl::EndDrag(const CPoint& point)
{
	m_bDragging = FALSE;
	ReleaseCapture();
	if (m_pView == NULL || m_pDragGraphic == NULL)
		return;

	CDC* pDC = GetDC();
	m_pView->put_DC((long)pDC->m_hDC);
	VARIANT varState;
	varState.vt = VT_I4;
	varState.lVal = imsiDragEnd;
	HRESULT hRes = m_pView->DragOutline(&m_dragOutline, point.x, point.y, &varState);
	ReleaseDC(pDC);

	VariantClear(&m_dragOutline);

	double dx, dy;
	hRes = m_pView->ScreenToView(point.x, point.y, &dx, &dy);
	dx -= m_dragX;
	dy -= m_dragY;
	hRes = m_pDragGraphic->MoveRelative(dx, dy, 0.0, NULL);
	m_pDragGraphic->put_Visible(TRUE);
	m_pDragGraphic->Release();
	m_pDragGraphic = NULL;
	InvalidateControl();
}

void CSDKDemoCtrl::OnLButtonDown(UINT nFlags, CPoint point) 
{
	m_ptMouseDown = point;
	if (m_pDragGraphic != NULL)
	{
		m_pDragGraphic->Release();
		m_pDragGraphic = NULL;
	}

	if (m_pView != NULL)
	{
		HRESULT hRes = m_pView->ScreenToView(point.x, point.y, &m_dragX, &m_dragY);
		PickResult* pickResult;
		hRes = m_pView->PickPoint(m_dragX, m_dragY, 
			&varMissing, // Aperture
			&varMissing, // TopLevel, 
			&varMissing, // Arcs 
			&varMissing, // Text 
			&varMissing, // Segments 
			&varMissing, // Blocks 
			&varMissing, // Invisible 
			&pickResult);
		if (SUCCEEDED(hRes))
		{
			long lCount = 0;
			hRes = pickResult->get_Count(&lCount);
			if (lCount > 0)
			{
				COleVariant varIndex(0L);
				PickEntry* pickEntry;
				hRes = pickResult->get_Item(&varIndex, &pickEntry);
				if (SUCCEEDED(hRes))
				{
					IGraphic* pIGraphic;
					hRes = pickEntry->get_Graphic(&pIGraphic);
					if (SUCCEEDED(hRes))
						m_pDragGraphic = pIGraphic;
					pickEntry->Release();
				}
			}
			pickResult->Release();
		}
	}

	COleControl::OnLButtonDown(nFlags, point);
}

void CSDKDemoCtrl::OnLButtonUp(UINT nFlags, CPoint point) 
{
	if (m_bDragging)
		EndDrag(point);
	else if (m_pDragGraphic != NULL)
	{
		m_pDragGraphic->Release();
		m_pDragGraphic = NULL;
	}
	
	COleControl::OnLButtonUp(nFlags, point);
}

void CSDKDemoCtrl::OnMouseMove(UINT nFlags, CPoint point) 
{
	if (m_pDragGraphic != NULL && !m_bDragging && (nFlags & MK_LBUTTON))
	{
		if (!BeginDrag(point))
		{
			m_pDragGraphic->Release();
			m_pDragGraphic = NULL;
		}
	}
	else if (m_bDragging)
	{
		if (nFlags & MK_LBUTTON)
			Drag(point);
		else
			EndDrag(point);
	}
	
	COleControl::OnMouseMove(nFlags, point);
}

SDK Top API Reference TurboCAD Home Page TurboCAD Programming Forums